package nz.ac.massey.doi_information_extractor.parser;

import java.io.BufferedInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import nz.ac.massey.doi_information_extractor.data.Author;
import nz.ac.massey.doi_information_extractor.data.AuthorList;
import nz.ac.massey.doi_information_extractor.data.Publication;

public class ScienceDirectExportPlugin implements PluginInterface {

	private String doi;
	private Publication result = new Publication();

	public ScienceDirectExportPlugin(String inputdoi) {
		this.doi = inputdoi;
	}

	@Override
	public void getInformationFromDOI(String doi) throws PublicationNotFoundException,
			IOException {

		URL redirectPage;
		try {
			if (doi.contains("dx.doi.org")) {
				redirectPage = new URL(doi);
			}
			else {
				redirectPage = new URL("http://dx.doi.org/" + doi);
			}
		} catch (MalformedURLException e) {
			throw new PublicationNotFoundException(e.getMessage());
		}

		URLConnection nextPage = redirectPage.openConnection();

		BufferedInputStream buffer = new BufferedInputStream(
				nextPage.getInputStream());

		StringBuilder builder = new StringBuilder();
		int byteRead;
		while ((byteRead = buffer.read()) != -1){
			builder.append((char) byteRead);
		}
		buffer.close();

		// Put the source together.
		String source = builder.toString();

		// Now go to the export citation tool.
		String url = "";
		Pattern urlPatt = Pattern.compile(
				"<li class=\"featureCount\">\n<a href=\"/.*\"", Pattern.UNIX_LINES);
		Matcher urlMat = urlPatt.matcher(source);
		if (urlMat.find() == true) {
			url = source.substring(urlMat.start(), urlMat.end());
		}
		if (url != "") {
			url = url.substring(35,url.length()-1);
			url = url.split("\"")[0];
		}
		else {
			throw new PublicationNotFoundException();
		}

		try {
				redirectPage = new URL("http://www.sciencedirect.com".concat(url));
		} catch (MalformedURLException e) {
			throw new PublicationNotFoundException(e.getMessage());
		}

		nextPage = redirectPage.openConnection();

		buffer = new BufferedInputStream(
				nextPage.getInputStream());

		builder = new StringBuilder();
		while ((byteRead = buffer.read()) != -1){
			builder.append((char) byteRead);
		}
		buffer.close();

		// Put the source together.
		source = builder.toString();

		// Now go to the export citation tool.
		url = "";
		urlPatt = Pattern.compile(
				"<input type=hidden name=_ob value=DownloadURL>.*<script language=\"JavaScript\" type=\"text/javascript\">", Pattern.DOTALL);
		urlMat = urlPatt.matcher(source);
		if (urlMat.find() == true) {
			url = source.substring(urlMat.start(), urlMat.end());

		}
		if (url != "") {
			String[] parameters = url.split("\n");
			for (int i = 0; i < parameters.length; i++){
				parameters[i] = parameters[i].trim();
			}

		try {
				redirectPage = new URL("http://www.sciencedirect.com/science");
		} catch (MalformedURLException e) {
			throw new PublicationNotFoundException(e.getMessage());
		}
		nextPage = redirectPage.openConnection();
		nextPage.setDoInput(true);
		nextPage.setDoOutput(true);
		nextPage.setUseCaches(false);
		String content = "_ob=DownloadURL" +
							"&_method=finish" +
							"&_acct=" + parameters[3].substring(36,parameters[3].length() -1) +
							"&_userid=" + parameters[6].substring(38,parameters[6].length() -1) +
							"&_docType=" + parameters[9].substring(39,parameters[9].length() -1) +
							"&_uoikey=" + parameters[16].substring(38,parameters[16].length() -1) +
							"&count=" +parameters[20].substring(36,parameters[20].length() -1) +
							"&md5=" + parameters[23].substring(34,parameters[23].length() -1) +
							"&JAVASCRIPT_ON=Y" +
							"&format=cite-abs" +
							"&citation-type=BIBTEX" +
							"&Export=Export" +
							"&RETURN_URL=" + URLEncoder.encode("http://www.sciencedirect.com/science/home","UTF-8");

		DataOutputStream printout = new DataOutputStream (nextPage.getOutputStream ());
		printout.writeBytes(content);
		printout.flush ();
	    printout.close ();

		}
		else {
			throw new PublicationNotFoundException();
		}

		buffer = new BufferedInputStream(
				nextPage.getInputStream());

		builder = new StringBuilder();
		while ((byteRead = buffer.read()) != -1){
			builder.append((char) byteRead);
		}
		buffer.close();

		// Put the source together.
		source = builder.toString();

		String[] bits = source.split("\n");

		try {
			result.setArticleTitle(bits[1].substring(9, bits[1].length() - 3));

			result.setPublicationTitle(bits[2].substring(11,
					bits[2].length() - 3));

			result.setVolumeNumber(bits[3].substring(10, bits[3].length() - 3));

			result.setEdition(bits[4].substring(10, bits[4].length() - 3));

			result.setPageNumbers(bits[5].substring(9, bits[5].length() - 3));

			result.setIssn(bits[8].substring(8, bits[8].length() - 3));

			String[] authorsFurtherString = bits[11].substring(10, bits[11].length() -3 ).split(" ");
			// This is a little more tricky than the other methods, as it has to
			// fill the AuthorList with Author objects. It will make mistakes if
			// someone is called 'and'.
			AuthorList authors = new AuthorList();
			Author tempAuthor = new Author();
			for (int i = 0; i < authorsFurtherString.length; i++) {

				if (authorsFurtherString[i].equals("and")) {
					continue;
				}

				if (tempAuthor.getAuthorFirstName() == "") {
					tempAuthor.setAuthorFirstName(authorsFurtherString[i]);
				} else {
					tempAuthor.setAuthorLastName(authorsFurtherString[i]);
					authors.add(tempAuthor);
					tempAuthor = new Author();
				}
			}

			result.setAuthors(authors);

		} catch (NullPointerException e) {
			return;
		}
	}


	@Override
	public Publication call() throws Exception {
		getInformationFromDOI(doi);
		return result;
	}
}
